package middleware

import (
	"github.com/gin-gonic/gin"

	"BookStack/internal/interfaces/presenter"
	"BookStack/pkg/errors"
)

// ErrorHandler 错误处理中间件
func ErrorHandler(formatter presenter.ResponseFormatter) gin.HandlerFunc {
	return func(c *gin.Context) {
		// 处理请求
		c.Next()

		// 检查是否有错误
		if len(c.Errors) > 0 {
			// 获取第一个错误
			err := c.Errors.Last().Err

			// 检查是否为AppError类型
			if appErr, ok := err.(errors.AppError); ok {
				// 直接使用已经定义的应用错误
				formatter.Error(c, appErr)
				c.Abort()
				return
			}

			// 使用统一错误处理函数解析错误
			appErr := errors.ParseRequestBodyError(err)
			formatter.Error(c, appErr)

			// 终止后续中间件
			c.Abort()
		}
	}
}

// RecoveryHandler 恢复处理中间件
func RecoveryHandler(formatter presenter.ResponseFormatter) gin.HandlerFunc {
	return func(c *gin.Context) {
		defer func() {
			if r := recover(); r != nil {
				var err error
				switch x := r.(type) {
				case string:
					err = errors.New(errors.ErrCodeSystem, x)
				case error:
					err = errors.Wrap(x, errors.ErrCodeSystem, "")
				default:
					err = errors.New(errors.ErrCodeSystem, "未知错误")
				}

				// 记录错误日志
				c.Error(err)

				// 响应错误
				formatter.Error(c, err)

				// 终止请求
				c.Abort()
			}
		}()

		c.Next()
	}
}
